#ifndef _ROSTERPACKET_H_
#define _ROSTERPACKET_H_

#include <set>
#include <list>

#include <packet/IQ.h>

/**
 * Represents XMPP roster packets.
 *
 * @author Matt Tucker
 */
class RosterPacket : public IQ {
public:
	typedef enum {
		/**
		 * undefined
		 */
		UNDERFINED,

        /**
         * The user and subscriber have no interest in each other's presence.
         */
		NONE,

        /**
         * The user is interested in receiving presence updates from the subscriber.
         */
		TO,

        /**
         * The subscriber is interested in receiving presence updates from the user.
         */
		FROM,

        /**
         * The user and subscriber have a mutual interest in each other's presence.
         */
		BOTH,

        /**
         * The user wishes to stop receiving presence updates from the subscriber.
         */
		REMOVE
    } ITEM_TYPE;
	
    /**
     * A roster item, which consists of a JID, their name, the type of subscription, and
     * the groups the roster item belongs to.
     */
	class ItemStatus ;

    class Item {
	public:        
		/**
         * Creates a new roster item.
         *
         * @param user the user.
         * @param name the user's name.
         */
        Item(std::string user, std::string name);
		
        /**
         * Returns the user.
         *
         * @return the user.
         */
		std::string getUser() {
            return user;
        }

        /**
         * Returns the user's name.
         *
         * @return the user's name.
         */
		std::string getName() {
            return name;
        }

        /**
         * Sets the user's name.
         *
         * @param name the user's name.
         */
        void setName(std::string & name) {
            this->name = name;
        }
		
        /**
         * Returns the roster item type.
         *
         * @return the roster item type.
         */
        ITEM_TYPE getItemType() {
            return itemType;
        }

        /**
         * Sets the roster item type.
         *
         * @param itemType the roster item type.
         */
        void setItemType(ITEM_TYPE itemType) {
            this->itemType = itemType;
        }

        /**
         * Returns the roster item status.
         *
         * @return the roster item status.
         */
        ItemStatus * getItemStatus() {
            return itemStatus;
        }

        /**
         * Sets the roster item status.
         *
         * @param itemStatus the roster item status.
         */
        void setItemStatus(ItemStatus * itemStatus) {
            this->itemStatus = itemStatus;
        }

        /**
         * Returns an unmodifiable set of the group names that the roster item
         * belongs to.
         *
         * @return an unmodifiable set of the group names.
         */
		std::set<std::string> getGroupNames() {
            return groupNames;
        }

        /**
         * Adds a group name.
         *
         * @param groupName the group name.
         */
        void addGroupName(std::string groupName) {
            groupNames.insert(groupName);
        }

        /**
         * Removes a group name.
         *
         * @param groupName the group name.
         */
        void removeGroupName(std::string groupName) {
            groupNames.erase(groupName);
        }
		
		std::string toXML();

	private:
		std::string user;
		std::string name;
        ITEM_TYPE itemType;
        ItemStatus * itemStatus;
		std::set<std::string> groupNames;
	};

    /**
     * The subscription status of a roster item. An optional element that indicates
     * the subscription status if a change request is pending.
     */
    class ItemStatus {
	public: 
        /**
         * Request to subcribe.
         */
        static ItemStatus * SUBSCRIPTION_PENDING;

        /**
         * Request to unsubscribe.
         */
        static ItemStatus * UNSUBCRIPTION_PENDING;

        //static ItemStatus * fromString(std::string & value);

		std::string toString() {
            return value;
        }
	private:
		
        /**
         * Returns the item status associated with the specified string.
         *
         * @param value the item status.
         */
        ItemStatus(std::string & value) : value(value) {}

		std::string value;

    };


    /**
     * Adds a roster item to the packet.
     *
     * @param item a roster item.
     */
    void addRosterItem(Item * item) {
        //synchronized (rosterItems) {
        rosterItems.push_back(item); 
        //}
    }

    /**
     * Returns the number of roster items in this roster packet.
     *
     * @return the number of roster items.
     */
    int getRosterItemCount() {
        //synchronized (rosterItems) {
        return rosterItems.size();
        //}
    }

    /**
     * Returns an unmodifiable collection for the roster items in the packet.
     *
     * @return an unmodifiable collection for the roster items in the packet.
     */
	std::list<Item*> getRosterItems() {
        //synchronized (rosterItems) {
        return rosterItems;
        //}
    }
	
	std::string getChildElementXML();
	

private:
	std::list<Item*> rosterItems;

};

#endif // -- _ROSTERPACKET_H_
